from flask import request
from flask_restx import Resource, Namespace, fields
from app.utils.auth import token_required
from app.utils.validators import validate_required_fields
from app.services.role_service import RoleService
from app.services.menu_service import MenuService
from app.models.role import Role
from . import admin_bp

# 创建角色命名空间
roles_ns = Namespace('roles', description='角色管理相关接口')

# 定义请求模型
role_create_request = roles_ns.model('RoleCreateRequest', {
    'name': fields.String(required=True, description='角色名称'),
    'code': fields.String(description='角色编码'),
    'description': fields.String(description='角色描述'),
    'sort': fields.Integer(description='排序'),
    'status': fields.Boolean(description='状态')
})

role_update_request = roles_ns.model('RoleUpdateRequest', {
    'name': fields.String(description='角色名称'),
    'code': fields.String(description='角色编码'),
    'description': fields.String(description='角色描述'),
    'sort': fields.Integer(description='排序'),
    'status': fields.Boolean(description='状态')
})

role_permission_request = roles_ns.model('RolePermissionRequest', {
    'id': fields.Integer(required=True, description='角色ID'),
    'menu': fields.List(fields.Integer, description='菜单ID列表'),
    'data_range': fields.Integer(description='数据权限范围')
})

role_menu_request = roles_ns.model('RoleMenuRequest', {
    'menu_ids': fields.List(fields.Integer, required=True, description='菜单ID列表')
})

# Flask-RESTX兼容的响应函数
def success_response(data=None, message='操作成功', code=200):
    """成功响应格式 - Flask-RESTX兼容版本"""
    response = {
        'code': code,
        'message': message,
        'data': data
    }
    return response, code

def error_response(message='操作失败', code=400, data=None):
    """错误响应格式 - Flask-RESTX兼容版本"""
    response = {
        'code': code,
        'message': message,
        'data': data
    }
    return response, code

def paginate_response(query, page, per_page, total=None):
    """分页响应格式 - Flask-RESTX兼容版本"""
    if total is None:
        total = query.count()
    
    items = query.offset((page - 1) * per_page).limit(per_page).all()
    
    data = {
        'list': [item.to_dict() if hasattr(item, 'to_dict') else item for item in items],
        'pagination': {
            'page': page,
            'per_page': per_page,
            'total': total,
            'pages': (total + per_page - 1) // per_page
        }
    }
    
    return success_response(data)

@roles_ns.route('')
class RoleListAPI(Resource):
    """角色列表"""
    
    @token_required
    def get(self, current_admin):
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        keyword = request.args.get('keyword', '')
        status = request.args.get('status', type=int)
        
        if status is not None:
            status = bool(status)
        
        query, page, per_page = RoleService.get_list(page, per_page, keyword, status)
        return paginate_response(query, page, per_page)
    
    @roles_ns.expect(role_create_request)
    @token_required
    def post(self, current_admin):
        # 验证必填字段
        is_valid, error_msg = validate_required_fields(['name'])
        if not is_valid:
            return error_response(error_msg, 400)
        
        data = request.get_json()
        
        try:
            role = RoleService.create(data)
            return success_response(role.to_dict(), '创建成功')
        except Exception as e:
            return error_response(f'创建失败：{str(e)}', 500)


@roles_ns.route('/<int:role_id>')
class RoleDetailAPI(Resource):
    """角色详情"""
    
    @token_required
    def get(self, current_admin, role_id):
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        return success_response(role.to_dict())
    
    @roles_ns.expect(role_update_request)
    @token_required
    def put(self, current_admin, role_id):
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        data = request.get_json()
        
        try:
            updated_role = RoleService.update(role_id, data)
            return success_response(updated_role.to_dict(), '更新成功')
        except Exception as e:
            return error_response(f'更新失败：{str(e)}', 500)
    
    @token_required
    def delete(self, current_admin, role_id):
        result = RoleService.delete(role_id)
        if isinstance(result, tuple):
            success, message = result
            if not success:
                return error_response(message, 400)
            return success_response(message=message)
        else:
            if not result:
                return error_response('删除失败，角色不存在', 404)
            return success_response(message='删除成功')


@roles_ns.route('/<int:role_id>/menus')
class RoleMenuAPI(Resource):
    """角色菜单权限"""
    
    @token_required
    def get(self, current_admin, role_id):
        """获取角色菜单权限配置数据"""
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        # 获取完整菜单树结构（用于权限配置）
        menu_tree = MenuService.get_tree_for_permission()
        
        # 获取角色已选择的菜单ID
        role_menu_ids = RoleService.get_role_menus(role_id)
        
        data = {
            'menu_tree': menu_tree,
            'role_menu_ids': role_menu_ids or [],
            'role': role.to_dict()
        }
        
        return success_response(data)
    
    @roles_ns.expect(role_menu_request)
    @token_required
    def put(self, current_admin, role_id):
        """保存角色菜单权限"""
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        data = request.get_json()
        menu_ids = data.get('menu_ids', [])
        
        success = RoleService.set_role_menus(role_id, menu_ids)
        if not success:
            return error_response('设置失败', 500)
        
        return success_response(message='权限设置成功')


@roles_ns.route('/permission')
class RolePermissionAPI(Resource):
    """角色权限保存（兼容旧的API）"""
    
    @roles_ns.expect(role_permission_request)
    @token_required
    def put(self, current_admin):
        """保存角色权限配置"""
        data = request.get_json()
        role_id = data.get('id')
        menu_ids = data.get('menu', [])
        data_scope = data.get('data_range')
        
        if not role_id:
            return error_response('角色ID不能为空', 400)
        
        role = RoleService.get_by_id(role_id)
        if not role:
            return error_response('角色不存在', 404)
        
        try:
            # 更新菜单权限
            if menu_ids is not None:
                RoleService.set_role_menus(role_id, menu_ids)
            
            # 更新数据权限范围
            if data_scope is not None:
                # 将前端的数字映射为后端的字符串
                scope_mapping = {
                    0: Role.DATA_SCOPE_SELF,
                    1: Role.DATA_SCOPE_DEPT,
                    2: Role.DATA_SCOPE_DEPT_AND_CHILD,
                    3: Role.DATA_SCOPE_ALL,
                    4: Role.DATA_SCOPE_CUSTOM
                }
                
                if data_scope in scope_mapping:
                    update_data = {'data_scope': scope_mapping[data_scope]}
                    RoleService.update(role_id, update_data)
            
            return success_response(message='权限设置成功')
        except Exception as e:
            return error_response(f'设置失败：{str(e)}', 500)


@roles_ns.route('/data-scope-options')
class RoleDataScopeAPI(Resource):
    """角色数据权限选项"""
    
    @token_required
    def get(self, current_admin):
        """获取数据权限选项"""
        data_scope_choices = Role.get_data_scope_choices()
        return success_response(data_scope_choices)


# 将命名空间注册到统一的API实例
from . import api
api.add_namespace(roles_ns, path='/roles') 